package com.zxq.iot.tcp.modbus.rabbitmq;


import com.alibaba.fastjson.JSON;
import com.zxq.factory.FastFrame;
import com.zxq.frame.core.ExchangeDTO;
import com.zxq.iot.tcp.modbus.frame.TcpModBusFrame;
import com.zxq.iot.tcp.modbus.frame.inner.PDU;
import lombok.extern.slf4j.Slf4j;
import org.apache.xmlbeans.impl.util.HexBin;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.apache.commons.lang3.StringUtils;


@Component
@Slf4j
public class RabbitSubscribeHelper {

    @Autowired
    RabbitPublishHelper rabbitPublishHelper;


    /**
     * wen层下发，需要再次包装数据，下发到设备
     * @param exchangeDTO 交换数据
     * @throws Exception
     */
    @RabbitListener(queues = "${spring.rabbitmq.template.web-queue}")
    public void receiveWebChannel(ExchangeDTO exchangeDTO) throws Exception {

      byte[] pduBuff = exchangeDTO.getData();
      String pdu_message =  String.format("receive web => %s", exchangeDTO.getStringFormatMsg());
      log.info(pdu_message);


      TcpModBusFrame tcpModBusFrame = new TcpModBusFrame();

      tcpModBusFrame.setTransactionId(0);
      tcpModBusFrame.setProtocolId(0);
      tcpModBusFrame.setLength(pduBuff.length);
      PDU pdu = new PDU();
      FastFrame.decoder(pdu,pduBuff);
      log.info("pdu:" + pdu);
      tcpModBusFrame.setPdu(pdu);
      byte[] tcp_modbus_frame = FastFrame.encoder(tcpModBusFrame);

      String tcp_modbus_message =  String.format("receive web device:%s " +
              "tcp-modbus-frame:%s", exchangeDTO.getDevId(), HexBin.bytesToString(tcp_modbus_frame));
      log.info(tcp_modbus_message);
      exchangeDTO.setData(tcp_modbus_frame);
      RabbitPublishHelper.getInstance().publishFrameToNetworkChannel(exchangeDTO);
    }


    /**
     * 设备层上报，需要解包后，再上传到web层
     * @param exchangeDTO 交换数据
     * @throws Exception
     */
    @RabbitListener(queues = "${spring.rabbitmq.template.network-queue}")
    public void receiveNetwork(ExchangeDTO exchangeDTO) throws Exception {
        byte[] frame = exchangeDTO.getData();
        log.info("receive device frame: " + exchangeDTO.getStringFormatMsg());
        if(frame == null || frame.length == 0) {
            log.info("error frame is empty!");
            return;
        }
        TcpModBusFrame tcpModBusFrame = new TcpModBusFrame();
        PDU pdu = new PDU();
        tcpModBusFrame.setPdu(pdu);
        FastFrame.decoder(tcpModBusFrame,frame);
        log.info("receive tcp-modbus:" + tcpModBusFrame);

        String cmdHex = intToHex(pdu.getAddress()) + intToHex(pdu.getFunCode()) + intToHex((int) pdu.getData()[0]);
        exchangeDTO.setCmdHex(cmdHex);
        exchangeDTO.setData(FastFrame.encoder(pdu));

        rabbitPublishHelper.publishFrameToWebChannel(exchangeDTO);
    }

    /**
     * int 转 hex码
      * @param value
     * @return
     */
    private String intToHex(Integer value){
      String hex =  StringUtils.leftPad(Integer.toHexString(value).toUpperCase(), 2, '0');
      return hex;
    }




}
